#include "window.h"
#include "xdg-shell.h"

#include <string>
#include <ukui-wayland-client.h>

#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

#include <assert.h>

namespace ukuiwaylandclient
{

window::window(display *disp, int width, int height)
    : m_display(disp)
    , m_width(width)
    , m_height(height)
{
    assert(m_display != nullptr && m_display->isInitialized());

    wl_compositor_t *compositor = m_display->compositor();
    if (compositor) {
        m_wl_surface = compositor->create_surface();
    }
}

window::~window()
{
}

void window::show()
{
    if (!m_xdg_toplevel) {
        m_xdg_surface = m_display->xdgWmBase()->get_xdg_surface(m_wl_surface);
        m_xdg_toplevel = m_xdg_surface->get_toplevel();
    }

    m_xdg_surface->on_configure() = [this](uint32_t serial) {
        m_xdg_surface->ack_configure(serial);
    };
    m_wl_surface->commit();
    m_display->roundtrip();

    std::string filename = "/tmp/ukui-wayland-client-XXXXXX";
    int fd = mkstemp((char *)filename.c_str());
    ftruncate(fd, m_width * m_height * 4);
    m_data = mmap(nullptr, m_width * m_height * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    wl_shm_pool_t *pool = m_display->shm()->create_pool(fd, m_width * m_height * 4);
    close(fd);
    m_buffer = pool->create_buffer(0, m_width, m_height, m_width * 4, WL_SHM_FORMAT_XRGB8888);

    for (int i = 0; i < m_width * m_height; ++i) {
        uint32_t *pixel = (uint32_t *)m_data + i;
        *pixel = 0xffff0000; // ARGB format: opaque red
    }

    m_wl_surface->attach(m_buffer, 0, 0);
    m_wl_surface->commit();

    delete pool;
}

void window::hide()
{
    if (m_xdg_toplevel) {
        delete m_xdg_toplevel;
        m_xdg_toplevel = nullptr;
    }
    if (m_xdg_surface) {
        delete m_xdg_surface;
        m_xdg_surface = nullptr;
    }

    m_wl_surface->attach(nullptr, 0, 0);
    m_wl_surface->commit();

    m_buffer->destroy();
    munmap(m_data, m_width * m_height * 4);
    m_data = nullptr;
}

void window::resize(int32_t width, int32_t height)
{
    m_width = width;
    m_height = height;
}

} // namespace ukuiwaylandclient